package com.fanrui.code.family;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.SqlSession;

import com.fanrui.code.dao.FamilyListDao;
import com.fanrui.code.db.jvmdb.JvmDao;
import com.fanrui.code.entity.Family;
import com.fanrui.code.entity.FamilyList;
import com.fanrui.code.entity.FamilyMapper;
import com.fanrui.code.thread.MainLoopPlus.StrongRunnable;
import com.fanrui.code.util.core.LoopThreadPool;
import com.fanrui.code.util.logger.Stdout;
import com.fanrui.code.util.SessionUtil;
import com.fanrui.proto.cmd.ReqAMemberUpgradePosition.PositonType;

public class FamilyDao extends JvmDao<FamilyEntity, Integer> {
	// singleton
	private FamilyDao() {
		super(FamilyEntity.class);
		LoopThreadPool.getInstance().scheduleAtFixedRate(new StrongRunnable() {

			@Override
			protected void strongRun() throws Exception {
				updateToDB();
			}

		}, 5, 5, TimeUnit.SECONDS);
	}

	private static class FamilyDaoSingleton {
		private static FamilyDao instance = new FamilyDao();
	}

	public static FamilyDao getInstance() {
		return FamilyDaoSingleton.instance;
	}

	/**
	 * 家族名的映射集合 key 家族名称
	 */
	protected ConcurrentMap<String, FamilyEntity> entities4FamilyName = new ConcurrentHashMap<String, FamilyEntity>();

	/**
	 * 定时更新需要修改的数据到数据库
	 */
	public void updateToDB() {
		if (modifiedEntities != null && !modifiedEntities.isEmpty()) {
			synchronized (modifiedEntities) {
				Stdout.GET().info("Family:定时更新数据到数据库!此次更新{}条数据", modifiedEntities.size());
				try (SqlSession session = SessionUtil.getSession()) {
					FamilyMapper um = session.getMapper(FamilyMapper.class);
					for (FamilyEntity familyEntity : modifiedEntities.keySet()) {
						um.updateByPrimaryKey(familyEntity.toFamily());
					}
					modifiedEntities.clear();
					session.commit();
					session.close();
				}
			}
		}

	}

	@Override
	protected Collection<FamilyEntity> dbFindAll() {
		List<FamilyEntity> result = new ArrayList<FamilyEntity>();
		try (SqlSession session = SessionUtil.getSession()) {
			FamilyMapper um = session.getMapper(FamilyMapper.class);
			Collection<Family> familyDatats = um.selectAllItem(); // 数据库中的家族信息
			if (familyDatats != null && !familyDatats.isEmpty()) {
				for (Family family : familyDatats) {
					FamilyEntity familyEntity = loadFamily(family);
					if (familyEntity.getOwer() != null) {
						result.add(familyEntity);
					}

				}
			}
			Stdout.GET().info("{}个家族被加载到内存中", result.size());
		}
		return result;
	}

	/**
	 * 查找家族
	 */
	public List<Family> dbFindByFamilyName(String familyName) {
		SqlSession session = SessionUtil.getSession();
		List<Family> familys = null;
		try {
			FamilyMapper mapper = session.getMapper(FamilyMapper.class);
			familys = mapper.queryByFamilyName(familyName);
			Stdout.GET().info("总共查找到{}条数据", familys.size());
			session.commit();
			session.close();
			;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return familys;
	}

	public FamilyEntity queryByFamilyName(String name) {
		// 获取所有的家族
		Collection<FamilyEntity> allFamily = dbFindAll();
		for (FamilyEntity f : allFamily) {
			if (name.equals(f.getFamilyName())) {
				return f;
			}
		}
		return null;
	}
	
	public FamilyEntity queryByFamilyId(Integer id) {
		// 获取所有的家族
		Collection<FamilyEntity> allFamily = dbFindAll();
		for (FamilyEntity f : allFamily) {
			if (id.equals(f.getId())) {
				return f;
			}
		}
		return null;
	}

	/**
	 * 根据族长id查询家族
	 */
	public FamilyEntity queryByOwerid(int owerId) {
		// 获取所有的家族
		Collection<FamilyEntity> allFamily = dbFindAll();
		for (FamilyEntity f : allFamily) {
			if (f.getOwer().getId() == owerId) {
				return f;
			}
		}
		return null;
	}

	/**
	 * 加载一个家族
	 */
	public FamilyEntity loadFamily(Family family) {
		FamilyEntity familyEntity = new FamilyEntity(family);
		return familyEntity;
	}

	@Override
	protected void OtherSave4jvm(FamilyEntity entity) {
		entities4FamilyName.put(entity.getFamilyName(), entity);
	}

	@Override
	protected void otherDelete4Jvm(FamilyEntity entity) {
		entities4FamilyName.remove(entity.getFamilyName(), entity);
	}

	@Override
	protected void dbSave(FamilyEntity t) {

	}

	@Override
	protected void dbDelete(Integer entityId) {
		if (entityId != null) {
			try (SqlSession seesion = SessionUtil.getSession()) {
				FamilyMapper um = seesion.getMapper(FamilyMapper.class);
				int result = um.deleteByPrimaryKey(entityId);
				if(result == 1) {
					seesion.commit();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 查看某个名称的家族是否存在
	 */
	public synchronized boolean familyIsExist(String familyName) {
		return entities4FamilyName.containsKey(familyName);
	}

	/**
	 * 创建一个家族 创建成功后加载到内存中
	 */
	public synchronized FamilyEntity createFamilyIFSuccessLoad(Family family) {
		if (family != null) {
			if (family.getFamilyName() == null || StringUtils.isBlank(family.getFamilyName())
					|| familyIsExist(family.getFamilyName())) {
				return null;
			}
			try (SqlSession seesion = SessionUtil.getSession()) {
				FamilyMapper um = seesion.getMapper(FamilyMapper.class);
				int result = um.insertSelective(family);
				if (result != 0) {
					// 把创始人加入到成员列表
					FamilyList fl = new FamilyList();
					fl.setClubId(family.getId());
					fl.setJointime(family.getFamilyCreateTime());
					fl.setPlayerId(family.getFamilyOwer());
					fl.setJob(PositonType.LevelOne_VALUE+1);
					fl.setClubIncome(0l);
					FamilyListDao.getInstance().insert(fl);
					
					FamilyEntity familyEntity = new FamilyEntity(family);
					jvmSave(familyEntity);
					return familyEntity;
				}
				seesion.commit();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	public synchronized void updateFamily(Family family) {
		if (family != null) {
			if (family.getFamilyName() == null || StringUtils.isBlank(family.getFamilyName())
					|| familyIsExist(family.getFamilyName())) {
				return;
			}
			try (SqlSession seesion = SessionUtil.getSession()) {
				FamilyMapper um = seesion.getMapper(FamilyMapper.class);
				um.updateByPrimaryKey(family);
				seesion.commit();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public Family selectByPrimaryKey(Integer id) {
		try (SqlSession seesion = SessionUtil.getSession()) {
			FamilyMapper um = seesion.getMapper(FamilyMapper.class);
			return um.selectByPrimaryKey(id);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
}
